/* ----

# Pio Plugin
# By: Dreamer-Paul
# Last Update: 2022.8.12

一个支持更换 Live2D 模型的 JS 插件

本代码为奇趣保罗原创，并遵守 GPL 2.0 开源协议。欢迎访问我的博客：https://paugram.com

---- */

export let Paul_Pio = function (prop) {
  const that = this;

  const current = {
    idol: 0,
    timeout: undefined,
    menu: document.querySelector(".pio-container .pio-action"),
    canvas: document.getElementById("pio"),
    body: document.querySelector(".pio-container"),
    root: document.location.protocol + "//" + document.location.hostname + "/"
  };

  // 工具通用函数
  const tools = {
    // 创建内容
    create: (tag, options) => {
      const el = document.createElement(tag);
      options.class && (el.className = options.class);

      return el;
    },
    // 随机内容
    rand: (arr) => {
      return arr[Math.floor(Math.random() * arr.length + 1) - 1];
    },
    // 是否为移动设备
    isMobile: () => {
      let ua = window.navigator.userAgent.toLowerCase();
      ua = ua.indexOf("mobile") || ua.indexOf("android") || ua.indexOf("ios");

      return window.innerWidth < 500 || ua !== -1;
    }
  }

  const elements = {
    home: tools.create("span", { class: "pio-home" }),
    skin: tools.create("span", { class: "pio-skin" }),
    info: tools.create("span", { class: "pio-info" }),
    night: tools.create("span", { class: "pio-night" }),
    close: tools.create("span", { class: "pio-close" }),

    dialog: tools.create("div", { class: "pio-dialog" }),
    show: tools.create("div", { class: "pio-show" })
  };

  current.body?.appendChild(elements.dialog);
  current.body?.appendChild(elements.show);

  /* - 方法 */
  const modules = {
    // 更换模型
    idol: () => {
      current.idol < (prop.model.length - 1) ? current.idol++ : current.idol = 0;

      return current.idol;
    },
    // 创建对话框方法
    message: (text, options = {}) => {
      const { dialog } = elements;

      if (text.constructor === Array) {
        dialog.innerText = tools.rand(text);
      }
      else if (text.constructor === String) {
        dialog[options.html ? "innerHTML" : "innerText"] = text;
      }
      else {
        dialog.innerText = "输入内容出现问题了 X_X";
      }

      dialog.classList.add("active");

      current.timeout = clearTimeout(current.timeout) || undefined;
      current.timeout = setTimeout(() => {
        dialog.classList.remove("active");
      }, options.time || 3000);
    },
    // 移除方法
    destroy: () => {
      that.initHidden();
      localStorage.setItem("posterGirl", "0");
    }
  };

  this.destroy = modules.destroy;
  this.message = modules.message;

  /* - 提示操作 */
  const action = {
    // 欢迎
    welcome: () => {
      if (document.referrer && document.referrer.includes(current.root)) {
        const referrer = document.createElement("a");
        referrer.href = document.referrer;

        if (prop.content.referer) {
          modules.message(prop.content.referer.replace(/%t/, `“${referrer.hostname}”`));
        }
        else {
          modules.message(`欢迎来自 “${referrer.hostname}” 的朋友！`);
        }
      }
      else if (prop.tips) {
        let text, hour = new Date().getHours();

        if (hour > 22 || hour <= 5) {
          text = "你是夜猫子呀？这么晚还不睡觉，明天起的来嘛";
        }
        else if (hour > 5 && hour <= 8) {
          text = "早上好！";
        }
        else if (hour > 8 && hour <= 11) {
          text = "上午好！工作顺利嘛，不要久坐，多起来走动走动哦！";
        }
        else if (hour > 11 && hour <= 14) {
          text = "中午了，工作了一个上午，现在是午餐时间！";
        }
        else if (hour > 14 && hour <= 17) {
          text = "午后很容易犯困呢，今天的运动目标完成了吗？";
        }
        else if (hour > 17 && hour <= 19) {
          text = "傍晚了！窗外夕阳的景色很美丽呢，最美不过夕阳红~";
        }
        else if (hour > 19 && hour <= 21) {
          text = "晚上好，今天过得怎么样？";
        }
        else if (hour > 21 && hour <= 23) {
          text = "已经这么晚了呀，早点休息吧，晚安~";
        }
        else {
          text = "奇趣保罗说：这个是无法被触发的吧，哈哈";
        }

        modules.message(text);
      }
      else {
        modules.message(prop.content.welcome || "欢迎来到本站！");
      }
    },
    // 触摸
    touch: () => {
      current.canvas.onclick = () => {
        modules.message(prop.content.touch || ["你在干什么？", "再摸我就报警了！", "HENTAI!", "不可以这样欺负我啦！"]);
      };
    },
    // 右侧按钮
    buttons: () => {
      // 返回首页
      elements.home.onclick = () => {
        location.href = current.root;
      };
      elements.home.onmouseover = () => {
        modules.message(prop.content.home || "点击这里回到首页！");
      };
      current.menu.appendChild(elements.home);

      // 更换模型
      if (prop.model && prop.model.length > 1) {
        elements.skin.onclick = () => {
          loadlive2d("pio", prop.model[modules.idol()]);

          prop.content.skin && modules.message(prop.content.skin[1] || "新衣服真漂亮~");
        };
        elements.skin.onmouseover = () => {
          prop.content.skin && modules.message(prop.content.skin[0] || "想看看我的新衣服吗？");
        };
        current.menu.appendChild(elements.skin);
      }

      // 关于我
      elements.info.onclick = () => {
        window.open(prop.content.link || "http://dai-lastyear.gitee.io/last-years-blog");
      };
      elements.info.onmouseover = () => {
        modules.message("想了解更多关于我的信息吗？");
      };
      current.menu.appendChild(elements.info);

      // 夜间模式
      if (prop.night) {
        elements.night.onclick = () => {
          typeof prop.night === "function" ? prop.night() : eval(prop.night);
        };
        elements.night.onmouseover = () => {
          modules.message("夜间点击这里可以保护眼睛呢");
        };
        current.menu.appendChild(elements.night);
      }

      // 关闭看板娘
      elements.close.onclick = () => {
        modules.destroy();
      };
      elements.close.onmouseover = () => {
        modules.message(prop.content.close || "QWQ 下次再见吧~");
      };
      current.menu.appendChild(elements.close);
    },
    // 自定义选择器
    custom: () => {
      prop.content.custom.forEach((item) => {
        const el = document.querySelectorAll(item.selector);

        if (!el.length) return;

        for (let i = 0; i < el.length; i++) {
          if (item.type === "read") {
            el[i].onmouseover = (ev) => {
              const text = ev.currentTarget.title || ev.currentTarget.innerText;
              modules.message("想阅读 %t 吗？".replace(/%t/, "“" + text + "”"));
            }
          }
          else if (item.type === "link") {
            el[i].onmouseover = (ev) => {
              const text = ev.currentTarget.title || ev.currentTarget.innerText;
              modules.message("想了解一下 %t 吗？".replace(/%t/, "“" + text + "”"));
            }
          }
          else if (item.text) {
            el[i].onmouseover = () => {
              modules.message(t.text);
            }
          }
        }
      });
    }
  };

  /* - 运行 */
  const begin = {
    static: () => {
      current.body.classList.add("static");
    },
    fixed: () => {
      action.touch();
      action.buttons();
    },
    draggable: () => {
      action.touch();
      action.buttons();

      const body = current.body;

      const location = {
        x: 0,
        y: 0
      };

      const mousedown = (ev) => {
        const { offsetLeft, offsetTop } = ev.currentTarget;

        location.x = ev.clientX - offsetLeft;
        location.y = ev.clientY - offsetTop;

        document?.addEventListener("mousemove", mousemove);
        document?.addEventListener("mouseup", mouseup);
      };

      const mousemove = (ev) => {
        body.classList.add("active");
        body.classList.remove("right");

        body.style.left = (ev.clientX - location.x) + "px";
        body.style.top = (ev.clientY - location.y) + "px";
        body.style.bottom = "auto";
      }

      const mouseup = () => {
        body.classList.remove("active");
        document.removeEventListener("mousemove", mousemove);
      }

      body.onmousedown = mousedown;
    }
  };

  // 运行
  this.init = (noModel) => {
    // 未隐藏 + 非手机版，出现操作功能
    if (!(prop.hidden && tools.isMobile())) {
      if (!noModel) {
        action.welcome();
        loadlive2d("pio", prop.model[0]);
      }

      switch (prop.mode) {
        case "static": begin.static(); break;
        case "fixed": begin.fixed(); break;
        case "draggable": begin.draggable(); break;
      }

      prop.content.custom && action.custom();
    }
  };

  // 隐藏状态
  this.initHidden = () => {
    // ! 清除预设好的间距
    if (prop.mode === "draggable") {
      current.body.style.top = null;
      current.body.style.left = null;
      current.body.style.bottom = null;
    }

    current.body.classList.add("hidden");
    elements.dialog.classList.remove("active");

    elements.show.onclick = () => {
      current.body.classList.remove("hidden");
      localStorage.setItem("posterGirl", "1");

      that.init();
    }
  }

  localStorage.getItem("posterGirl") === "0" ? this.initHidden() : this.init();
};

// 请保留版权说明
if (window.console && window.console.log) {
  console.log("%c Pio %c https://paugram.com ", "color: #fff; margin: 1em 0; padding: 5px 0; background: #673ab7;", "margin: 1em 0; padding: 5px 0; background: #efefef;");
}
